//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

package webhook_serv_harbor

import (
	"encoding/json"
	"fmt"
	"net/http"
	"time"

	"atomgit.com/openlinksaas/api-server/dao/event_dao"
	"atomgit.com/openlinksaas/proto-gen-go.git/events_api"
	harbor_hook "atomgit.com/openlinksaas/webhook.git/harbor"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"google.golang.org/protobuf/types/known/anypb"
)

var sourceType zapcore.Field

func init() {
	sourceType = zap.String("sourceType", "harbor")
}

func Process(projectId, eventSourceId string, header http.Header, payload []byte, secret string, logger *zap.Logger) (*event_dao.EventStageDbItem, *anypb.Any, error) {
	logger.Info("recive event", zap.String("projectId", projectId), zap.String("eventSourceId", eventSourceId), sourceType)
	timeStamp := time.Now().UnixNano() / 1e6
	hook := &harbor_hook.HarborHook{}
	err := json.Unmarshal(payload, hook)
	if err != nil {
		logger.Error("unmarshal failed", zap.String("projectId", projectId), zap.String("eventSourceId", eventSourceId), sourceType, zap.String("payload", string(payload)))
		return nil, nil, err
	}

	var eventAny *anypb.Any
	if hook.Type == "PUSH_ARTIFACT" {
		eventAny, err = anypb.New(hook.ToPushArtifactEvent())
	} else if hook.Type == "DELETE_ARTIFACT" {
		eventAny, err = anypb.New(hook.ToDeleteArtifactEvent())
	} else if hook.Type == "UPLOAD_CHART" {
		eventAny, err = anypb.New(hook.ToUploadChartEvent())
	} else if hook.Type == "DELETE_CHART" {
		eventAny, err = anypb.New(hook.ToDeleteChartEvent())
	}
	if err != nil {
		logger.Error("convert event failed", zap.String("projectId", projectId), zap.String("eventSourceId", eventSourceId), sourceType)
		return nil, nil, err
	}
	if eventAny == nil {
		logger.Error("event not support", zap.String("projectId", projectId), zap.String("eventSourceId", eventSourceId), sourceType, zap.String("payload", string(payload)))
		return nil, nil, fmt.Errorf("event not support")
	}
	sourceUserName := hook.Operator
	sourceDisplayName := hook.Operator
	stageItem := &event_dao.EventStageDbItem{
		ProjectId:         projectId,
		EventSourceId:     eventSourceId,
		SourceUserName:    sourceUserName,
		SourceDisplayName: sourceDisplayName,
		EventType:         uint32(events_api.EVENT_TYPE_EVENT_TYPE_HARBOR),
		EventTime:         timeStamp,
	}
	return stageItem, eventAny, nil
}
